# -*- coding:UTF-8 -*-
import os
import wx
import wx.xrc
import wx.lib.agw.ribbon as rb
from core.file_system import FileSystem, FileType
from gui.file_item_panel import FileItemPanel
from gui.cloud_setting_dialog import CloudSettingDialog
from gui.benchmark_folder_dialog import BenchmarkFolderDialog
from config.config import config
from gui.file_search_dialog import FileSearchDialog
from gui.hint_dialogs import WarmingDialog
from infrastructure.constant.Image_size_enum import ImageSizeEnum
from infrastructure.utils.id_utils import IdFactory
from gui.wx_style import WxBitmap
from favicon import get_favicon_path


class MainFrame(wx.Frame):

    def __init__(self, parent=None):
        wx.Frame.__init__(self, parent, id=IdFactory.generate_int_id(), title=u"LiFeng Note", pos=wx.DefaultPosition,
                          size=wx.Size(800, 600), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)
        self.SetBackgroundColour(wx.Colour(255, 255, 255))
        self.base_path = config.get('file', 'base_path')
        self.current_cloud = None
        self.file_system: FileSystem = None
        self.SetIcon(wx.Icon(name=get_favicon_path(key="LF", size=ImageSizeEnum.s16X16), type=wx.BITMAP_TYPE_ICO))

        self.SetSizeHints(wx.DefaultSize, wx.DefaultSize)

        bSizer1 = wx.BoxSizer(wx.VERTICAL)

        self.ribbonBar = rb.RibbonBar(self, IdFactory.generate_int_id(), wx.DefaultPosition, wx.DefaultSize,
                                      wx.lib.agw.ribbon.RIBBON_BAR_DEFAULT_STYLE | wx.lib.agw.ribbon.RIBBON_BAR_SHOW_PAGE_LABELS)
        # self.ribbonPage_file = rb.RibbonPage(self.ribbonBar, IdFactory.generate_int_id(), u"文件", WxBitmap.get("open", size=ImageSizeEnum.s16X16), 0)
        # self.ribbonPanel_file = rb.RibbonPanel(self.ribbonPage_file, IdFactory.generate_int_id(), u"文件", WxBitmap.get("open", size=ImageSizeEnum.s16X16),
        #                                        wx.DefaultPosition, wx.DefaultSize,
        #                                        wx.lib.agw.ribbon.RIBBON_PANEL_DEFAULT_STYLE)
        # self.ribbonButtonBar_file = rb.RibbonButtonBar(self.ribbonPanel_file, IdFactory.generate_int_id(), wx.DefaultPosition,
        #                                                wx.DefaultSize, 0)
        # self.ribbonButtonBar_file.AddSimpleButton(wx.ID_OPEN, u"打开选中文件", WxBitmap.get("open", size=ImageSizeEnum.s16X16), wx.EmptyString)
        # self.ribbonButtonBar_file.Bind(rb.EVT_RIBBONBUTTONBAR_CLICKED, self.open_select_file, id=wx.ID_OPEN)
        # self.ribbonButtonBar_file.AddSimpleButton(wx.ID_SAVE, u"保存", WxBitmap.get("save", size=ImageSizeEnum.s16X16), wx.EmptyString)
        # self.ribbonButtonBar_file.Bind(rb.EVT_RIBBONBUTTONBAR_CLICKED, self.save_slect_file, id=wx.ID_SAVE)
        # self.ribbonButtonBar_file.AddSimpleButton(wx.ID_REFRESH, u"刷新", WxBitmap.get("save", size=ImageSizeEnum.s16X16), wx.EmptyString)
        # self.ribbonButtonBar_file.Bind(rb.EVT_RIBBONBUTTONBAR_CLICKED, self.refresh_files, id=wx.ID_REFRESH)
        #
        # self.ribbonPage_view = rb.RibbonPage(self.ribbonBar, IdFactory.generate_int_id(), u"查看", WxBitmap.get("view", size=ImageSizeEnum.s16X16), 0)
        # self.ribbonPanel_layout = rb.RibbonPanel(self.ribbonPage_view, IdFactory.generate_int_id(), u"布局", WxBitmap.get("open", size=ImageSizeEnum.s16X16),
        #                                          wx.DefaultPosition, wx.DefaultSize, 0)
        # self.ribbonButtonBar_layout = rb.RibbonButtonBar(self.ribbonPanel_layout, IdFactory.generate_int_id(), wx.DefaultPosition,
        #                                                  wx.DefaultSize, 0)
        # self.b_detail_id = IdFactory.generate_int_id()
        # self.ribbonButtonBar_layout.AddSimpleButton(self.b_detail_id, u"详细信息", WxBitmap.get("open", size=ImageSizeEnum.s16X16), wx.EmptyString)
        # self.b_tree_id = IdFactory.generate_int_id()
        # self.ribbonButtonBar_layout.AddSimpleButton(self.b_tree_id, u"目录树", WxBitmap.get("open", size=ImageSizeEnum.s16X16), wx.EmptyString)
        # self.b_little_icon_id = IdFactory.generate_int_id()
        # self.ribbonButtonBar_layout.AddSimpleButton(IdFactory.generate_int_id(), u"小图标", WxBitmap.get("open", size=ImageSizeEnum.s16X16), wx.EmptyString)
        # self.ribbonPanel_sort = rb.RibbonPanel(self.ribbonPage_view, IdFactory.generate_int_id(), u"排序", WxBitmap.get("open", size=ImageSizeEnum.s16X16),
        #                                        wx.DefaultPosition, wx.DefaultSize,
        #                                        wx.lib.agw.ribbon.RIBBON_PANEL_DEFAULT_STYLE)
        # self.ribbonButtonBar_sort = rb.RibbonButtonBar(self.ribbonPanel_sort, IdFactory.generate_int_id(), wx.DefaultPosition,
        #                                                wx.DefaultSize, 0)
        # self.b_sort_name_id = IdFactory.generate_int_id()
        # self.b_sort_type_id = IdFactory.generate_int_id()
        # self.b_sort_update_date_id = IdFactory.generate_int_id()
        # self.ribbonButtonBar_sort.AddSimpleButton(self.b_sort_name_id, u"名称", WxBitmap.get("open", size=ImageSizeEnum.s16X16), wx.EmptyString)
        # self.ribbonButtonBar_sort.AddSimpleButton(self.b_sort_type_id, u"类型", WxBitmap.get("open", size=ImageSizeEnum.s16X16), wx.EmptyString)
        # self.ribbonButtonBar_sort.AddSimpleButton(self.b_sort_update_date_id, u"修改日期", WxBitmap.get("open", size=ImageSizeEnum.s16X16), wx.EmptyString)
        # self.ribbonButtonBar_sort.AddDropdownButton(IdFactory.generate_int_id(), u"排序方式", WxBitmap.get("open", size=ImageSizeEnum.s16X16), wx.EmptyString)

        self.ribbonPage_setup = rb.RibbonPage(self.ribbonBar, IdFactory.generate_int_id(), u"设置", WxBitmap.get("open", size=ImageSizeEnum.s16X16), 0)
        self.ribbonBar.SetActivePage(self.ribbonPage_setup)
        self.ribbonPanel_benchmark_filder = rb.RibbonPanel(self.ribbonPage_setup, IdFactory.generate_int_id(), u"基准文件夹", WxBitmap.get("open", size=ImageSizeEnum.s16X16),
                                                           wx.DefaultPosition, wx.DefaultSize,
                                                           wx.lib.agw.ribbon.RIBBON_PANEL_DEFAULT_STYLE)
        self.ribbonButtonBar_benchmark_folder = rb.RibbonButtonBar(self.ribbonPanel_benchmark_filder, IdFactory.generate_int_id(), wx.DefaultPosition, wx.DefaultSize, 0)
        self.ribbonButtonBar_benchmark_folder_id = IdFactory.generate_int_id()
        self.ribbonButtonBar_benchmark_folder.AddSimpleButton(self.ribbonButtonBar_benchmark_folder_id, u"选择基准文件夹", WxBitmap.get("open", size=ImageSizeEnum.s16X16), wx.EmptyString)
        self.ribbonButtonBar_benchmark_folder.Bind(rb.EVT_RIBBONBUTTONBAR_CLICKED, self.setup_benchmark_folder, id=self.ribbonButtonBar_benchmark_folder_id)

        self.ribbonPanel_cloud_set = rb.RibbonPanel(self.ribbonPage_setup, IdFactory.generate_int_id(), u"设置云",
                                                    wx.NullBitmap,
                                                    wx.DefaultPosition, wx.Size( -1,-1 ),
                                                    wx.lib.agw.ribbon.RIBBON_PANEL_STRETCH)
        self.cloud_setting_ribbonToolBar = rb.RibbonToolBar(self.ribbonPanel_cloud_set, IdFactory.generate_int_id(),
                                                            wx.DefaultPosition,
                                                            wx.Size( -1,-1 ), 0)
        for name in FileType.file_types():
            self.cloud_setting_ribbonToolBar.AddSimpleTool(IdFactory.generate_int_id(key=name),
                                                           WxBitmap.get(name, size=ImageSizeEnum.s64X64),
                                                           help_string=name)
        self.cloud_setting_ribbonToolBar.Bind(rb.EVT_RIBBONTOOLBAR_CLICKED, self.cloud_setting_dialag)

        self.ribbon_panel_cloud_select = rb.RibbonPanel(self.ribbonPage_setup, IdFactory.generate_int_id(), u"选择云", wx.NullBitmap,
                                                        wx.DefaultPosition, wx.Size( -1,-1 ),
                                                        wx.lib.agw.ribbon.RIBBON_PANEL_STRETCH)
        self.ribbonGallery_cloud_select_id = IdFactory.generate_int_id()
        self.ribbonGallery_cloud_select = rb.RibbonGallery(self.ribbon_panel_cloud_select, self.ribbonGallery_cloud_select_id, wx.DefaultPosition, wx.Size( -1,-1 ), 0)
        self.ribbonGallery_cloud_select.Bind(rb.EVT_RIBBONGALLERY_SELECTED, self.selected_cloud_changed, id=self.ribbonGallery_cloud_select_id)
        self.set_benchmark_folder(self.base_path)

        self.ribbonBar.Realize()
        bSizer1.Add(self.ribbonBar, 0, wx.EXPAND, 0)

        bSizer2 = wx.BoxSizer(wx.HORIZONTAL)

        self.b_goback = wx.BitmapButton(self, IdFactory.generate_int_id(), WxBitmap.get("left", size=ImageSizeEnum.s16X16), wx.DefaultPosition, wx.DefaultSize,
                                        wx.BU_AUTODRAW)
        bSizer2.Add(self.b_goback, 0, wx.EXPAND | wx.LEFT, 0)
        self.b_goback.Bind(wx.EVT_BUTTON, self.backward)

        self.b_forward = wx.BitmapButton(self, IdFactory.generate_int_id(), WxBitmap.get("right", size=ImageSizeEnum.s16X16), wx.DefaultPosition, wx.DefaultSize,
                                         wx.BU_AUTODRAW)
        bSizer2.Add(self.b_forward, 0, wx.EXPAND, 0)
        self.b_forward.Bind(wx.EVT_BUTTON, self.forward)

        # __init__(self, parent=None, id=None, bitmap=None, pos=None, size=None, style=None, validator=None, name=None)
        # self.b_history = wx.BitmapButton(self, IdFactory.generate_int_id(), WxBitmap.get("down", size=ImageSizeEnum.s16X16), wx.DefaultPosition, wx.DefaultSize,
        #                                  wx.BU_AUTODRAW)
        # bSizer2.Add(self.b_history, 0, wx.EXPAND, 0)

        self.b_go_parent_path = wx.BitmapButton(self, IdFactory.generate_int_id(), WxBitmap.get("up", size=ImageSizeEnum.s16X16), wx.DefaultPosition, wx.DefaultSize,
                                                wx.BU_AUTODRAW)
        bSizer2.Add(self.b_go_parent_path, 0, wx.EXPAND, 0)
        self.b_go_parent_path.Bind(wx.EVT_BUTTON, self.go_parent)

        self.t_path = wx.TextCtrl(self, IdFactory.generate_int_id(), wx.EmptyString, wx.DefaultPosition, wx.Size(-1, -1), wx.TE_AUTO_URL)
        bSizer2.Add(self.t_path, 1, wx.ALIGN_CENTER | wx.EXPAND | wx.LEFT, 0)
        self.t_path.Bind(wx.EVT_TEXT_ENTER, self.t_path_enter)

        self.b_refresh = wx.BitmapButton(self, IdFactory.generate_int_id(), WxBitmap.get("refresh", size=ImageSizeEnum.s16X16), wx.DefaultPosition, wx.DefaultSize,
                                         wx.BU_AUTODRAW)
        self.b_refresh.Bind(wx.EVT_BUTTON, self.t_path_enter)
        bSizer2.Add(self.b_refresh, 0, wx.EXPAND, 0)

        self.t_search = wx.TextCtrl(self, IdFactory.generate_int_id(key="search"), wx.EmptyString, wx.DefaultPosition, wx.Size(-1, -1), wx.TE_LEFT)
        self.t_search.SetMaxLength(200)
        self.t_search.SetMinSize(wx.Size(100, -1))
        self.t_search.SetMaxSize(wx.Size(200, -1))
        self.t_search.Bind(wx.EVT_TEXT_ENTER, self.to_search)
        bSizer2.Add(self.t_search, 1, wx.ALIGN_CENTER | wx.EXPAND | wx.RIGHT | wx.LEFT, 0)
        self.b_search = wx.BitmapButton(self, IdFactory.generate_int_id(),
                                         WxBitmap.get("search", size=ImageSizeEnum.s16X16), wx.DefaultPosition,
                                         wx.DefaultSize,
                                         wx.BU_AUTODRAW)
        self.b_search.Bind(wx.EVT_BUTTON, self.to_search)
        bSizer2.Add(self.b_search, 0, wx.EXPAND, 0)

        bSizer1.Add(bSizer2, 0, wx.EXPAND, 5)

        bSizer3 = wx.BoxSizer(wx.HORIZONTAL)

        self.treeCtrl_left = wx.TreeCtrl(self, IdFactory.generate_int_id(), wx.DefaultPosition, wx.DefaultSize, wx.TR_DEFAULT_STYLE)
        self.treeCtrl_left.SetMinSize(wx.Size(150, -1))
        self.treeCtrl_left.SetMaxSize(wx.Size(200, -1))

        bSizer3.Add(self.treeCtrl_left, 0, wx.EXPAND, 0)

        self.file_item_panel = FileItemPanel(self, file=None)
        bSizer3.Fit(self.file_item_panel)
        bSizer3.Add(self.file_item_panel, 0, wx.EXPAND, 5)

        bSizer1.Add(bSizer3, 1, wx.EXPAND | wx.BOTTOM | wx.RIGHT, 0)

        self.SetSizer(bSizer1)
        self.Layout()
        self.statusBar = self.CreateStatusBar(1, wx.ST_NO_AUTORESIZE, IdFactory.generate_int_id())
        self.Centre(wx.BOTH)

        # Connect Events


        # self.ribbonButtonBar_layout.Bind(rb.EVT_RIBBONBUTTONBAR_CLICKED, self.detail_file, id=self.b_detail_id)
        # self.ribbonButtonBar_layout.Bind(rb.EVT_RIBBONBUTTONBAR_CLICKED, self.tree_file, id=self.b_tree_id)
        # self.ribbonButtonBar_layout.Bind(rb.EVT_RIBBONBUTTONBAR_CLICKED, self.little_icon_file, id=self.b_little_icon_id)
        # self.ribbonButtonBar_sort.Bind(rb.EVT_RIBBONBUTTONBAR_CLICKED, self.sort_name, id=self.b_sort_name_id)
        # self.ribbonButtonBar_sort.Bind(rb.EVT_RIBBONBUTTONBAR_DROPDOWN_CLICKED, self.sort_type, id=self.b_sort_type_id)
        # self.ribbonButtonBar_sort.Bind(rb.EVT_RIBBONBUTTONBAR_CLICKED, self.sort_update_date, id=self.b_sort_update_date_id)
        # self.ribbonToolBar_select_cloud.Bind(wx.EVT_LEFT_DCLICK, self.generate_online_cloud)
        self.Bind(rb.EVT_RIBBONTOOLBAR_CLICKED, self.cloud_setting, id=IdFactory.generate_int_id())

        # self.ribbon_panel_cloud.Bind(wx.EVT_ENTER_WINDOW, self.setup_ribbon_panel_cloud)
        self.treeCtrl_left.Bind(wx.EVT_TREE_SEL_CHANGED, self.left_tree_select_change)
        self.treeCtrl_left.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.left_tree_expending)

    def __del__(self):
        pass

    # Virtual event handlers, overide them in your derived class
    def save_slect_file(self, event):
        event.Skip()

    def open_select_file(self, event):
        self.file_item_panel.treelist_process("打开")

    def refresh_files(self, event):
        self.file_item_panel.treelist_process("刷新")

    def save_select(self, event):
        event.Skip()

    def detail_file(self, event):
        print("detail_file ")
        event.Skip()

    def tree_file(self, event):
        event.Skip()

    def little_icon_file(self, event):
        event.Skip()

    def sort_name(self, event):
        event.Skip()

    def sort_type(self, event):
        menu = wx.Menu()
        menu.Append(IdFactory.generate_int_id(), "递增")
        menu.Append(IdFactory.generate_int_id(), "递减")
        event.PopupMenu(menu)

    def sort_update_date(self, event):
        event.Skip()

    def generate_online_cloud(self):
        self.ribbonGallery_cloud_select.Clear()
        if self.file_system is not None and self.file_system.files is not None and len(self.file_system.files) > 0:
            for file in self.file_system.files:
                item = self.ribbonGallery_cloud_select.Append(WxBitmap.get(file.name, size=ImageSizeEnum.s16X16), id=IdFactory.generate_int_id(), clientData=file)
                item.SetIsVisible(True)
        item = self.ribbonGallery_cloud_select.Append(WxBitmap.get("_"), id=IdFactory.generate_int_id(), clientData=None)
        item.SetIsVisible(False)
        self.ribbonBar.Realize()

    def selected_cloud_changed(self, event):
        item:wx.lib.agw.ribbon.gallery.RibbonGalleryItem = event.EventObject.GetActiveItem()
        clientData = item.GetClientData()
        if not clientData:
            event.Skip()
        else:
            self.left_tree_root()

    def setup_benchmark_folder(self, event):
        """
        设置基准目录事件处理函数
        :param event:
        :return:
        """
        path = None if not self.file_system else self.file_system.base
        BenchmarkFolderDialog(self, path=path).Show()

    def set_benchmark_folder(self, path:str):
        """
        设置基准目录
        :param path: 需要存在且为目录
        :return:
        """
        base_path = config.get('file', 'base_path')
        if path is not None and os.path.exists(path) and os.path.isdir(path):
            self.base_path = path
            if base_path != path:
                config.new_or_update('file', 'base_path', path)
            self.file_system = FileSystem(base=path)
            self.generate_online_cloud()

    def setup_ribbon_panel_cloud(self, event):
        event.Skip()

    def left_tree_select_change(self, event):
        item = event.GetItem()
        file = self.treeCtrl_left.GetItemData(event.GetItem())
        self.file_item_panel.refresh(file, type="tree")

    def left_tree_expending(self, event):
        if event.EventObject and event.Item:
            item_data = event.EventObject.GetItemData(event.Item)
            if item_data and item_data.is_folder:
                first_item = event.EventObject.GetFirstChild(event.Item)[0]
                if first_item and not event.EventObject.GetItemData(first_item):
                    self.treeCtrl_left.Delete(first_item)
                try:
                    first_item = event.EventObject.GetFirstChild(event.Item)[0]
                    event.EventObject.GetItemData(first_item)
                except:
                    if item_data.get_child_size() > 0:
                        for name, item_child in item_data:
                            if item_child.is_folder:
                                subitem = self.treeCtrl_left.AppendItem(parent=event.Item, text=item_child.get_name(), image=0, data=item_child)
                                self.treeCtrl_left.AppendItem(parent=subitem, text="", data=None)

    def left_tree_root(self):
        file = self.ribbonGallery_cloud_select.GetActiveItem().GetClientData()
        imglist = wx.ImageList(16, 16, True, 2)
        imglist.Add(wx.ArtProvider.GetBitmap(wx.ART_FOLDER, size=wx.Size(16, 16)))
        imglist.Add(wx.ArtProvider.GetBitmap(wx.ART_NORMAL_FILE, size=ImageSizeEnum.s16X16.value))
        self.treeCtrl_left.AssignImageList(imglist)
        if file:
            self.treeCtrl_left.DeleteAllItems()
            root = self.treeCtrl_left.AddRoot(file.name, image=0, data=file)
            for name, item in file:
                if item.is_folder:
                    subitem = self.treeCtrl_left.AppendItem(parent=root, text=item.get_name(), image=0, data=item)
                    self.treeCtrl_left.AppendItem(parent=subitem, text="", data=None)
            self.treeCtrl_left.Expand(root)
            self.treeCtrl_left.SelectItem(root)

    def cloud_setting(self, event):
        event.Skip()

    def cloud_menu(self, event):
        menu = wx.Menu()
        file_type_list = FileType.file_types()
        if file_type_list or len(file_type_list) > 0:
            for file_type in file_type_list:
                menuItem = wx.MenuItem(id=IdFactory.generate_int_id(), text=file_type)
                menu.AppendItem(menuItem=menuItem)
                menu.Bind(wx.EVT_MENU, self.cloud_setting_dialag, id=menuItem.GetId())
        event.PopupMenu(menu)

    def cloud_setting_dialag(self, event):
        if self.file_system is not None:
            file_class = FileType.get_file_class(IdFactory.get_key_by_id(event.Id))
            if file_class:
                self.current_cloud = file_class
                CloudSettingDialog(self).Show()
            else:
                event.Skip()
        else:
            WarmingDialog(self, msg="请先设置基准目录").Show()
            event.Skip()

    def set_cloud(self, settings:dict):
        if self.current_cloud:
            config.new_or_update_batch(self.current_cloud.name, settings)
            file_clazz = FileType.get_file_class(self.current_cloud.name)
            file = self.file_system.get_top_file(file_clazz)
            if file:
                file.refresh()
            else:
                file = file_clazz(relative_path="", base=self.file_system.base)
                self.file_system.add_top_file(file)
        self.generate_online_cloud()

    def cloud_ribbon_button_click(self, event):
        print("cloud_ribbon_button_click")

    def t_path_enter(self, event):
        file = None
        try:
            root_item = self.treeCtrl_left.GetRootItem()
            if root_item:
                file = self.treeCtrl_left.GetItemData(root_item)
        except:
            pass
        if file:
            path = event.String if event.String is not None and len(event.String) > 0 else self.t_path.Value
            item = file.get_file(path=path)
            if item:
                self.file_item_panel.refresh(item)
        else:
            event.Skip()

    def to_search(self, event):
        text = event.String if event.String is not None and len(event.String) > 0 else self.t_search.Value
        FileSearchDialog(self, self.file_item_panel.file, s=text).Show()

    def backward(self, event):
        self.file_item_panel.backward()

    def forward(self, event):
        self.file_item_panel.forward()

    def go_parent(self, event):
        self.file_item_panel.go_parent()